package org.rc.parsing;

import java.util.Calendar;
import org.rc.model.Athlete;
import org.rc.model.Race;
import org.rc.model.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Parse a result line from a file in the standard tab seperated layout from the old card system
 * Race Name : 0
 * Distance miles : 1
 * Date : 2
 * First name : 5
 * Second Name : 6
 * Category : 7
 * Club : 8
 * Time : 10
 * Place : 9
 * 
 * @author dokeeffe
 */
public class StandardFormatParser implements ResultsLineParser {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(ResultsLineParser.class);
    
    /**
     * The delimiter for the file this will process is tab
     */
    private static final String DELIMITER = "\t";

    /**
     * Split athletes by club, if true a seperate Athlete will be created for "John Doe Leavale AC" and "John Doe Eagle AC"
     */
    private boolean SPLIT_ATHLETES_BY_CLUB = false;

    /**
     * {@inheritDoc }
     * @param line
     * @return 
     */
    @Override
    public ResultDetails parse(String line) {
        //LOGGER.debug("parsing line: " + line);
        try {
            ResultDetails rd = new ResultDetails();
            String[] elements = line.split(DELIMITER);
            rd.setRace(parseRace(elements));
            rd.setAthlete(parseAthlete(elements));
            rd.setResult(parseResult(elements, rd.getRace()));
            return rd;
        } catch(Throwable t) {
            LOGGER.error("error parsing line" + line , t);
            return null;
        }
     }

    
    /**
     * Parse a Race
     * @param elements
     * @return
     */
    protected Race parseRace(String[] elements) {
        Race race = new Race();
        race.setName(elements[0]);
        String[] ymd = elements[2].split("-");
        int year = Integer.parseInt(ymd[0]);
        int month = Integer.parseInt(ymd[1])-1;
        int date = Integer.parseInt(ymd[2]);
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(year, month, date,10,10,10);
        race.setDate(cal.getTime());
        double miles = Double.parseDouble(elements[1]);
        race.setMiles(miles);
        return race;
    }

    /**
     * Parse a line into a REsult
     * @param data
     * @param race
     * @return 
     */
    protected Result parseResult(String[] data, Race race) {
        Result res = new Result();
        res.setRecordedAthleteName(filterFirstName(data) + " " + filterSecondName(data));
        res.setClub(data[8]);
        String[] time = data[10].split(":");
        res.setHours(Integer.parseInt(time[0]));
        res.setMin(Integer.parseInt(time[1]));
        res.setSec(Integer.parseInt(time[2]));
        res.setCategory(data[7]);
        res.setPlace(Integer.parseInt(data[9]));
        res.setSecondsPerMilePace(calcPace(res, race));
        return res;
    }

    /**
     * Parse an Athlete from the results file line.
     * @param data
     * @return
     */
    protected Athlete parseAthlete(String[] data) {
        Athlete a = new Athlete();
        if (SPLIT_ATHLETES_BY_CLUB) {
            String club = data[8];
            if (club.contains("AC")) {
                club = club.replace("AC", "").trim();
            }
            a.setClub(club);
        }
        a.setFirstName(filterFirstName(data));
        a.setSecondName(filterSecondName(data));
        return a;
    }

    private String filterSecondName(String[] data) {
        return data[6].replace("' ", "").replace("Mc ", "Mc");
    }

    private String filterFirstName(String[] data) {
        return data[5].replace(" ", "");
    }
    
    /**
     * calculate the pace for this result
     * @param res
     * @return
     */
    protected Long calcPace(Result res, Race race) {
        double miles = race.getMiles();
        double seconds = (res.getHours()*60*60) + (res.getMin()*60) + res.getSec();
        return Math.round(seconds/miles);
    }
}
